﻿//This C# code file was released under the Ms-PL license
//http://www.opensource.org/licenses/ms-pl.html
//This script was originally intended for use with Microsoft Dynamics AX
//and maintained and distributed as a project on CodePlex
//http://dynamicsaxbuild.codeplex.com

using System;
using System.Collections.Generic;
using System.Text;
using System.Activities;
using Microsoft.Win32;
using System.ServiceProcess;
using Microsoft.TeamFoundation.Build.Client;

namespace AXTFSBuildLibrary
{
    public enum ServiceStatus
    {
        Started,
        Stopped
    }

    /// <summary>
    /// The AOSService class allows stopping/starting of AOS service,
    /// based on a server name and service identifier
    /// </summary>
    [BuildActivity(HostEnvironmentOption.All)]
    public sealed class AOSService : CodeActivity
    {
        /// <summary>
        /// Name of the AOS server (machine)
        /// </summary>
        [RequiredArgument]
        public InArgument<string> ServerName { get; set; }
        /// <summary>
        /// Service identifier (e.g. AOS60$01)
        /// </summary>
        [RequiredArgument]
        public InArgument<string> ServiceIdentifier { get; set; }
        /// <summary>
        /// Desired status of the AOS service
        /// </summary>
        [RequiredArgument]
        public InArgument<ServiceStatus> NewStatus { get; set; }
        /// <summary>
        /// Maximum number of minutes to wait for completion of status change
        /// </summary>
        [RequiredArgument]
        public InArgument<UInt16> TimeOutMinutes { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            string serviceIdentifier = ServiceIdentifier.Get(context);

            // If the service identifier is blank, no AOS could be found for our server/port
            if (String.IsNullOrWhiteSpace(serviceIdentifier))
            {
                throw new Exception("Service identifier not defined");
            }

            string serverName = ServerName.Get(context);
            if (String.IsNullOrWhiteSpace(serverName))
            {
                throw new Exception("Server name not defined");
            }

            ServiceStatus newStatus = NewStatus.Get(context);

            UInt16 timeout = TimeOutMinutes.Get(context);

            // Create a service controller instance for the AOS service
            ServiceController service = new ServiceController(serviceIdentifier, serverName);
            switch (newStatus)
            {
                case ServiceStatus.Started:
                    if (service.Status == ServiceControllerStatus.Running)
                        return;
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, timeout, 0));
                    break;
                case ServiceStatus.Stopped:
                    if (service.Status == ServiceControllerStatus.Stopped)
                        return;
                    service.Stop();
                    service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, timeout, 0));
                    break;
            }
        }
    }
}
